﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CountDate
{
    class CalcDate
    {
        public class DTime
        {
            public int Year { get; set;}
            public int Month { get; set; }
            public int Day { get; set; }

            public DTime(int yr, int mo, int dy)
            {
                Year = yr;
                Month = mo;
                Day = dy;
            }
        }

        // algorithm:
        // giveng a string, parse it to a DateTime structure
        // then count the days of the structure with regard to year 0/0/0000
        // then add the days with the given N, thus get the new days
        // then from the new days, get the DTime

        static void Main(string[] args)
        {
            // test method
            CalcDate cdate = new CalcDate();
            DTime dt1 = cdate.GetNewDTimeFromN("08/09/2011", 2);
            DTime dt2 = cdate.GetNewDTimeFromN("08/09/2011", -2);
        }

        DTime GetNewDTimeFromN(string dtimeString, int num)
        {
            int numberOfDaysNow = GetNumberOfDays(GetDTimeFromString(dtimeString));
            DTime newDTime = GetDTimeFromNumber(numberOfDaysNow + num);

            return newDTime;
        }

        //given a string like "08/09/2011", parse it to a class 
        // assume the input string is always in the format of "mm/dd/yyyy"
        DTime GetDTimeFromString(string dtimeString)
        {
            string[] strtok = dtimeString.Split('/');
            if (strtok.Length != 3)
            {
                Console.WriteLine("Danger!");
                throw new Exception();
            }

            return new DTime(int.Parse(strtok[2]), int.Parse(strtok[0]), int.Parse(strtok[1]));
        }



        // given a DTime structure, return the number of days with regard to 0/0/0000
        int GetNumberOfDays(DTime dtime)
        {
            // assume no leap years, it is easy to calculate the days: years * 365 + months * sth + days
            int year_days = (dtime.Year - 1) * 365;
            int month_days = GetDaysFromMonth(dtime.Month);
            return year_days + month_days + dtime.Day;
        }

        // given a month, return the number of days of the year up to the previous month
        int GetDaysFromMonth(int mon)
        {
            int numDays = 0;
            switch (mon)
            {
                case 1:
                    break;
                case 2:
                    numDays += 31;
                    break;
                case 3:
                    numDays += 31 + 28;
                    break;
                case 4:
                    numDays += 31 + 28 + 31;
                    break;
                case 5:
                    numDays += 31 + 28 + 31 + 30;
                    break;
                case 6:
                    numDays += 31 + 28 + 31 + 30 + 31;
                    break;
                case 7:
                    numDays += 31 + 28 + 31 + 30 + 31 + 30;
                    break;
                case 8:
                    numDays += 31 + 28 + 31 + 30 + 31 + 30 + 31;
                    break;
                case 9:
                    numDays += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
                    break;
                case 10:
                    numDays += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
                    break;
                case 11:
                    numDays += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
                    break;
                case 12:
                    numDays += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
                    break;
            }
            return numDays;
        }

        // from the given number of days, get the DTime structure
        DTime GetDTimeFromNumber(int daysNumber)
        {
            int years = daysNumber / 365 + 1;
            int numberDaysOfYear = daysNumber % 365;
            int monthOfYear = GetMonthFromNumber(numberDaysOfYear);
            int dayOfYear = numberDaysOfYear - GetDaysFromMonth(monthOfYear);
            DTime dtime = new DTime(years, monthOfYear, dayOfYear);

            return dtime;
        }

        // given the days of a year, get its month value
        int GetMonthFromNumber(int daysNumber)
        {
            for (int i = 1; i < 12; i++)
            {
                if ((GetDaysFromMonth(i) < daysNumber) && (GetDaysFromMonth(i + 1) > daysNumber))
                    return i;
            }
            return 12;

        }
    }
}
